<?php

/**
 * Class Request
 */
class Request
{
    /**
     * @var array
     */
    protected $request;

    /**
     * @param array $request
     */
    public function __construct($request = array())
    {
        $this->request = array_merge($_GET, $_POST, $request);
    }

    /**
     * @param $method
     * @param $args
     * @return mixed|null
     * @throws Exception
     */
    public function __call($method, $args)
    {
        $prefix = substr($method, 0, 3);

        if ($prefix === 'get') {
            $field = $this->camel2uscore(substr($method, 3));

            if (!isset($this->request[$field])) {
                if (!empty($args)) {
                    return reset($args);
                }
                return null;
            }

            return $this->request[$field];
        }
        throw new Exception('Call undefined method');
    }

    /**
     * @param $str
     * @return string
     */
    protected function camel2uscore($str)
    {
        $replace = array_combine(range('A', 'Z'), array_map(function($n) { return '_' . $n; }, range('a', 'z')));
        return strtr(lcfirst($str), $replace);
    }

    /**
     * @param $arr
     * @return string
     */
    public function arr2str($arr)
    {
        $result = array();
        foreach ($arr as $key => $value) {
            $result[] = $key . '=' . urlencode($value);
        }
        return implode('&', $result);
    }

    /**
     * @return array
     */
    public function getAll()
    {
        return $this->request;
    }

    /**
     * @param $required
     * @return bool
     */
    public function validate($required) {
        $intersect = array_intersect_key($this->request, array_flip($required));
        return sizeof($required) == sizeof($intersect);
    }
}
